﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Device.Location;
using System.Threading;
using System.ComponentModel;

namespace GPSEmulator
{
    public class GPSEmulator : IGeoPositionWatcher<GeoCoordinate>
    {

        #region Properties

        public GeoPosition<GeoCoordinate> Position
        {
            get
            {
                return _position;
            }
            private set
            {
                _position = value;
                PositionChanged(this, new GeoPositionChangedEventArgs<GeoCoordinate>(Position));
            }
        }
        public double MovementTreshold { get; set; }
        public GeoPositionStatus Status
        {
            get
            {
                if (mainMethod == null) return GeoPositionStatus.Disabled;
                else return mainMethod.ThreadState == ThreadState.Running ? GeoPositionStatus.Ready : GeoPositionStatus.Disabled;
            }
            private set { ;}
        }

        #endregion

        #region Events
        // Summary:
        //     Indicates that the latitude or longitude of the location data has changed.
        public event EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>> PositionChanged;
        //
        // Summary:
        //     Indicates that the status of the System.Device.Location.GeoCoordinateWatcher
        //     object has changed.
        public event EventHandler<GeoPositionStatusChangedEventArgs> StatusChanged;
        #endregion

        #region Private Fields
        private Random rnd = new Random();
        private GeoPosition<GeoCoordinate> _position;
        private Thread mainMethod;

        private readonly GeoCoordinate UNIVERSITY = new GeoCoordinate(45.47946, 12.25604);

        #endregion

        #region Not implementedMethods
        public void Start(bool suppressPermissionPrompt)
        {
            throw new NotImplementedException();

        }
        public bool TryStart(bool suppressPermissionPrompt, TimeSpan timeout)
        {
            throw new NotImplementedException();
        }
        #endregion

        #region MyMehtods

        public GPSEmulator()
        {
            _position = new GeoPosition<GeoCoordinate>(DateTimeOffset.Now, UNIVERSITY);
            MovementTreshold = 0;
            mainMethod = new Thread(MainMethod);
        }
        public void hack(GeoCoordinate coord)
        {
            Position = new GeoPosition<GeoCoordinate>(DateTimeOffset.Now, coord);
        }

        #endregion

        #region InheritedMethods
        public void Start()
        {
            mainMethod.Start();
            StatusChanged(this, new GeoPositionStatusChangedEventArgs(GeoPositionStatus.Ready));
        }

        public void Stop()
        {
            mainMethod.Abort();
            StatusChanged(this, new GeoPositionStatusChangedEventArgs(GeoPositionStatus.Disabled));
        }
        #endregion

        #region Private Methods

        private void MainMethod()
        {
            while (true)
            {
                var pos = Position;
                var nlat = pos.Location.Latitude + (rnd.NextDouble() * 0.1);
                var nlong = pos.Location.Longitude + (rnd.NextDouble() * 0.1);
                var nloc = new GeoCoordinate(nlat, nlong);
                Position = new GeoPosition<GeoCoordinate>(DateTimeOffset.Now, nloc);
                Thread.Sleep(rnd.Next(3)*1000);
            }
        }

        #endregion

    }
}
